package org.kingtop.shiro.util;

import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.InputStream;
import java.security.Key;
import java.util.Date;
import java.util.Properties;

/**
 * jwt token 的加密和解析
 *
 * @author 陈金波
 * @date 2018 /2/9 21:14
 */
public class TokenUtil {

    /**
     * 配置文件名称
     */
    private static String PROPERTY_FILE = "application.properties";

    /**
     * 配置文件中属性的名称
     */
    private static String PROPERTY_NAME = "token";
    /**
     * @TODO 使用加密算法，然后在这边解密，再使用，防止别人看到
     */
    private static String APP_KEY = "why_key";

    private TokenUtil() {

    }

    /**
     * 读取配置文件中的私钥
     */
    static {
        String key = readProperty();
        APP_KEY = StringUtils.isBlank(key) ? APP_KEY : key;
    }

    /**
     * 一个JWT实际上就是一个字符串，它由三部分组成，头部(Header)、载荷(Payload)与签名(Signature)
     *
     * @param id        当前用户ID
     * @param issuer    该JWT的签发者，是否使用是可选的
     * @param subject   该JWT所面向的用户，是否使用是可选的
     * @param issuedAt  签发时间
     * @param ttlMillis 什么时候过期，毫秒数
     * @param audience  接收该JWT的一方，是否使用是可选的
     * @return
     */
    public static String createJWT(String id, String issuer, String subject, Date issuedAt, long ttlMillis, String audience) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = issuedAt.getTime();
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(APP_KEY);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        JwtBuilder jwtBuilder = Jwts.builder()
                .setId(id)
                .setSubject(subject)
                .setIssuedAt(issuedAt)
                .setIssuer(issuer)
                .setAudience(audience)
                .signWith(signatureAlgorithm, signingKey);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            jwtBuilder.setExpiration(exp);
        }

        return jwtBuilder.compact();

    }

    //

    /**
     * 私钥解密token信息，如果token是非法的，则抛出SignatureException，这个一个RuntimeException
     *
     * @param jwt token信息
     * @return 解密结果
     * @Author 陈金波
     * @Date 2018/2/9 22:48
     */
    public static Claims getClaims(String jwt) {
        return Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(APP_KEY))
                .parseClaimsJws(jwt).getBody();
    }

    /**
     * 读取配置文件中的私钥
     *
     * @return 私钥或者空
     */
    private static String readProperty() {
        String value = "";
        InputStream in = null;
        try {
            in = TokenUtil.class.getClassLoader().getResourceAsStream(PROPERTY_FILE);
            if (in == null) {
                return value;
            }
            Properties properties = new Properties();
            properties.load(in);
            value = properties.getProperty(PROPERTY_NAME);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return value;
    }


}
